home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 8 / FM Towns Free Software Collection 8.iso / t_os / zousan / src / tiff2.c < prev    next >
Text File  |  1994-06-01  |  18KB  |  889 lines

  1. /*
  2.  *   Tiff Load/Save function 2    By N.Takahashi
  3.  *
  4.  *       ver1.1 1994/02/02    Tiff LZW圧縮/展開 サポート
  5.  *       ver0.2 1994/01/30    Tiff 関数コール変更 + ファイル名変更
  6.  *       -----------------------
  7.  *       ver0.1 1993/11/15  初版
  8.  */
  9.  
  10. /* これらは、TIFF形式のグラフィックデータを扱うための関数です。 */
  11.  
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include "tiff2.h"
  15.  
  16.  
  17. /* LZW圧縮/展開  構造体 */
  18. typedef struct ntable {
  19.     unsigned char ch;
  20.     unsigned char cs;
  21.     short dmy;
  22.     struct ntable *next;
  23.     int code;
  24.     int hash;
  25.     int len;
  26. } TABLE;
  27.  
  28. typedef struct hchain {
  29.     TABLE *tbl;
  30.     struct hchain *next;
  31. } CHAIN;
  32.  
  33.  
  34. /* Tiff ヘッダ用 構造体 */
  35. struct tiffid {
  36.     char id[4];
  37.     unsigned int tagstart;
  38. };
  39.  
  40. struct tiffe {
  41.     char tdata1[8];
  42.     char tdata2[8];
  43. };
  44.  
  45. struct tifftag {
  46.     unsigned char tag[8];
  47.     unsigned int data;
  48. };
  49.  
  50.  
  51. /* 関数の重複回避用 (ちょっと強引かな...) */
  52. #define add_entry    Tiff__add_entry
  53. #define tsearch        Tiff__tsearch
  54. #define get_data    Tiff__get_data
  55. #define put_code    Tiff__put_code
  56.  
  57. #define add_table    Tiff__add_table
  58. #define get_code    Tiff__get_code
  59. #define put_table    Tiff__put_table
  60. #define init_table    Tiff__init_table
  61. #define free_mem    Tiff__free_mem
  62. #define alloc_mem    Tiff__alloc_mem
  63.  
  64. #define adjpal        Tiff__adjpal
  65. #define cmpdata        Tiff__cmpdata
  66.  
  67.  
  68. /* Prototype function */
  69. int Tiff__comp( int size, char *pmem, char *cmem );
  70. void add_entry( TABLE *s, int c );
  71. TABLE *tsearch( TABLE *s, int c );
  72. int get_data( void );
  73. void put_code( int ch );
  74.  
  75. int Tiff__decomp( char *pmem, char *xmem );
  76. void add_table( int s, int c );
  77. int get_code( void );
  78. void put_table( int code );
  79. void init_table( void );
  80. void free_mem( void );
  81. int alloc_mem( void );
  82.  
  83. void adjpal( char *pal, int pasize );
  84. int cmpdata( void *p1, void *p2, int n );
  85.  
  86.  
  87. /* Global variable */
  88.  
  89. /* エラーメッセージ */
  90. char *Tiff_err[]={
  91.     "正常です。",
  92.     "ファイルがオープン出来ません。",
  93.     "リードエラーです。",
  94.     "Tiff形式ではありません。",
  95.     "圧縮されていません。",
  96.     "メモリが足りません。",
  97.     "不正な色数です。",
  98.     "この圧縮法には対応していません。",
  99.     "不正な関数呼出しをしています。"
  100. };
  101.  
  102.  
  103. /* LZW圧縮/展開  広域変数 */
  104. #define CLEAR_CODE    256
  105. #define EOF_CODE    257
  106. #define MAXTABLE    4096    /* TiffLZWではこの値 */
  107. #define MAXHASH        4096    /* これ位が適当か */
  108.  
  109.  
  110. static CHAIN **Hash;        /* CHAIN *Hash[MAXHASH]  */
  111. static CHAIN *Chain;        /* CHAIN Chain[MAXTABLE] */
  112. static int Chain_ix=0;
  113.  
  114. static TABLE *Table;        /* TABLE Table[MAXTABLE] */
  115. static int Cbl;
  116. static int Table_ix;
  117. static char *Pmem, *Xmem, *Cmem;
  118. static int Psize;
  119. static int Cc,Ccl;
  120.  
  121.  
  122. /* Tiff ヘッダ用 広域変数 */
  123. static struct tiffid Tiff_id={
  124.     {0x49,0x49,0x2a,0x00},
  125.     0x00000008
  126. };
  127.  
  128. static struct tiffe Tiff_e1={
  129.     { 0x4b,0x00,0x00,0x00,0x01,0x00,0x00,0x00 },
  130.     { 0x4b,0x00,0x00,0x00,0x01,0x00,0x00,0x00 }
  131. };
  132.  
  133. static struct tiffe Tiff_e2={
  134.     { 0x4b,0x00,0x00,0x00,0x02,0x00,0x00,0x00 },
  135.     { 0x4b,0x00,0x00,0x00,0x02,0x00,0x00,0x00 }
  136. };
  137.  
  138. static struct tifftag Tiff_tag[17]={
  139.     { {0xfe,0x00,0x04,0x00,0x01,0x00,0x00,0x00}, 0x00000000 },
  140.     { {0x00,0x01,0x03,0x00,0x01,0x00,0x00,0x00}, 0x00000280 },
  141.     { {0x01,0x01,0x03,0x00,0x01,0x00,0x00,0x00}, 0x000001e0 },
  142.     { {0x02,0x01,0x03,0x00,0x01,0x00,0x00,0x00}, 0x00000004 },
  143.     { {0x03,0x01,0x03,0x00,0x01,0x00,0x00,0x00}, 0x00000001 },
  144.     { {0x06,0x01,0x03,0x00,0x01,0x00,0x00,0x00}, 0x00000001 },
  145.     { {0x0a,0x01,0x03,0x00,0x01,0x00,0x00,0x00}, 0x00000002 },
  146.     { {0x11,0x01,0x04,0x00,0x01,0x00,0x00,0x00}, 0x00000200 },
  147.     { {0x15,0x01,0x03,0x00,0x01,0x00,0x00,0x00}, 0x00000001 },
  148.     { {0x16,0x01,0x04,0x00,0x01,0x00,0x00,0x00}, 0x000001e0 },
  149.     { {0x17,0x01,0x04,0x00,0x01,0x00,0x00,0x00}, 0x00025800 },
  150.     { {0x19,0x01,0x03,0x00,0x01,0x00,0x00,0x00}, 0x0000000f },
  151.     { {0x1a,0x01,0x05,0x00,0x01,0x00,0x00,0x00}, 0x000001f0 },
  152.     { {0x1b,0x01,0x05,0x00,0x01,0x00,0x00,0x00}, 0x000001f8 },
  153.     { {0x1c,0x01,0x03,0x00,0x01,0x00,0x00,0x00}, 0x00000001 },
  154.     { {0x40,0x01,0x03,0x00,0x30,0x00,0x00,0x00}, 0x00000100 },
  155.     { {0x40,0x01,0x03,0x00,0x00,0x03,0x00,0x00}, 0x00000200 }
  156. };
  157.  
  158.  
  159. /* function */
  160.  
  161. /* 関数 Tiff_new : Tiff初期化
  162.    戻り値 = Tiffアクセス構造体のポインタ
  163. */
  164. Tiff *Tiff_new( void ) {
  165. Tiff *tp;
  166.     if( (tp=(Tiff *)malloc( sizeof( Tiff ) )) == NULL )
  167.         return( NULL );
  168.     tp->xsize = tp->ysize = tp->color = tp->comp = -1;
  169.     tp->gmsize = tp->pmsize = 0;
  170.     tp->gmem = tp->pmem = NULL;
  171.     return( tp );
  172. }
  173.  
  174.  
  175. /* 関数 Tiff_delete : Tiff削除
  176.    tp = Tiffアクセス構造体
  177. */
  178. void Tiff_delete( Tiff *tp ) {
  179.     if( tp!=NULL ) {
  180.         if( tp->gmem!=NULL )
  181.             free( tp->gmem );
  182.         if( tp->pmem!=NULL )
  183.             free( tp->pmem );
  184.         free( tp );
  185.         tp=NULL;
  186.     }
  187. }
  188.  
  189.  
  190. /* 関数 Tiff_setgraph : (非圧縮)画像データ設定
  191.    tp = Tiffアクセス構造体
  192.    xsize , ysize = 画像サイズ
  193.    color  = 色数
  194.    gmem   = 画像データ
  195.    pmem   = パレットデータ
  196. */
  197. int Tiff_setgraph( Tiff *tp, int xsize, int ysize, int color, void *gmem, void *pmem ) {
  198.     tp->xsize=xsize;
  199.     tp->ysize=ysize;
  200.     tp->color=color;
  201.     tp->comp=1;
  202.     tp->gmem=(char *)gmem;
  203.     tp->pmem=(char *)pmem;
  204.     tp->pmsize=0;
  205.     switch( color ) {
  206.         case 16:
  207.             tp->gmsize=xsize*ysize*4/8;
  208.             if( pmem!=NULL )
  209.                 tp->pmsize=16*3*2;
  210.             break;
  211.         case 256:
  212.             tp->gmsize=xsize*ysize*8/8;
  213.             if( pmem!=NULL )
  214.                 tp->pmsize=256*3*2;
  215.             break;
  216.         case 32768:
  217.             tp->gmsize=xsize*ysize*16/8;
  218.             break;
  219.         default:
  220.             return( Tiff__ILLCOL );
  221.     }
  222.     return( Tiff__OK );
  223. }
  224.  
  225.  
  226. /* 関数 Tiff_getgraph : (非圧縮)画像データ読みだし
  227.    xsize , ysize = 画像サイズ
  228.    color  = 色数
  229.    gmem   = 画像データ
  230.    pmem   = パレットデータ
  231.    tp = Tiffアクセス構造体
  232. */
  233. int Tiff_getgraph( int *xsize, int *ysize, int *color, char **gmem, char **pmem, Tiff *tp ) {
  234.     if( tp->comp!=1 )
  235.         return( Tiff__NOREAD );
  236.     *xsize=tp->xsize;
  237.     *ysize=tp->ysize;
  238.     *color=tp->color;
  239.     *gmem=tp->gmem;
  240.     *pmem=tp->pmem;
  241.     return( Tiff__OK );
  242. }
  243.  
  244.  
  245. /* 関数 Tiff_save : Tiff形式セーブ
  246.    fn = ファイル名
  247.    tp = Tiffアクセス構造体
  248. */
  249. int Tiff_save( char *fn, Tiff *tp ) {
  250. FILE *fp;
  251. int pt=0,p,i;
  252. char buf[16];
  253.  
  254.     if( tp->xsize<=0 || tp->ysize<=0
  255.      || tp->color<=0
  256.      || tp->gmem==NULL || tp->gmsize<=0
  257.      || ( tp->pmem!=NULL && tp->pmsize<=0 )
  258.       )
  259.         return( Tiff__ILLCALL );
  260.  
  261.  
  262.     p=( tp->pmem!=NULL )?3:1;
  263.     switch( tp->color ) {
  264.         case 2:
  265.             Tiff_tag[3].data=1;
  266.             Tiff_tag[5].data=0;
  267.             Tiff_tag[6].data=1;
  268.             Tiff_tag[7].data=0x200;
  269.             Tiff_tag[11].data=1;
  270.             break;
  271.         case 256:
  272.             Tiff_tag[3].data=8;
  273.             Tiff_tag[5].data=p;
  274.             Tiff_tag[6].data=1;
  275.             Tiff_tag[11].data=255;
  276.             if( tp->pmem!=NULL ) {
  277.                 Tiff_tag[7].data=0x800;
  278.                 pt=16;
  279.             }
  280.             else    
  281.                 Tiff_tag[7].data=0x200;
  282.             break;
  283.         case 32768:
  284.             Tiff_tag[3].data=16;
  285.             Tiff_tag[5].data=1;
  286.             Tiff_tag[6].data=1;
  287.             Tiff_tag[7].data=0x200;
  288.             Tiff_tag[11].data=32767;
  289.             break;
  290.         case 16:
  291.         default:
  292.             Tiff_tag[3].data=4;
  293.             Tiff_tag[5].data=p;
  294.             Tiff_tag[6].data=2;
  295.             Tiff_tag[7].data=0x200;
  296.             Tiff_tag[11].data=15;
  297.             if( tp->pmem!=NULL )
  298.                 pt=15;
  299.     }
  300.     Tiff_tag[1].data=tp->xsize;
  301.     Tiff_tag[2].data=tp->ysize;
  302.     Tiff_tag[9].data=tp->ysize;
  303.     Tiff_tag[4].data=tp->comp;
  304.     Tiff_tag[10].data=tp->gmsize;
  305.     
  306.     if( (fp=fopen( fn,"wb" ))==NULL )
  307.         return( Tiff__NOOPEN );
  308.     
  309.     fseek( fp, 0L, SEEK_SET );
  310.     for( i=0; i<16; i++ )
  311.         buf[i]=0;
  312.     for( i=0; i<32; i++ )
  313.         fwrite( buf, sizeof(char), 16, fp );
  314.     fseek( fp, 0L, SEEK_SET );
  315.     
  316.     fwrite( &Tiff_id, 1, sizeof(Tiff_id), fp );
  317.     *(unsigned short *)buf=( tp->pmem!=NULL )?16:15;
  318.     fwrite( buf, sizeof(char), 2, fp );
  319.     
  320.     for( i=0; i<15; i++ )
  321.         fwrite( &Tiff_tag[i], 1, sizeof(Tiff_tag[0]), fp );
  322.     
  323.     if( tp->pmem!=NULL ) {
  324.         fwrite( &Tiff_tag[pt], 1, sizeof(Tiff_tag[0]), fp );
  325.         *(unsigned int *)buf=0;
  326.         fwrite( buf, sizeof(char), 4, fp );
  327.         adjpal( tp->pmem, tp->pmsize );
  328.         fseek( fp, Tiff_tag[pt].data, SEEK_SET );
  329.         fwrite( tp->pmem, 1, tp->pmsize, fp );
  330.     }
  331.     else {
  332.         *(unsigned int *)buf=0;
  333.         fwrite( buf, sizeof(char), 4, fp );
  334.     }
  335.     
  336.     fseek( fp, 0x1f0L, SEEK_SET );
  337.     if( tp->color==32768 && tp->xsize<=320 )
  338.         fwrite( &Tiff_e2, 1, sizeof(Tiff_e2), fp );
  339.     else
  340.         fwrite( &Tiff_e1, 1, sizeof(Tiff_e1), fp );
  341.  
  342.     fseek( fp, Tiff_tag[7].data, SEEK_SET );
  343.     fwrite( tp->gmem, 1, tp->gmsize, fp );
  344.  
  345.     fclose( fp );
  346.     return( Tiff__OK );
  347. }
  348.  
  349.  
  350. /* 関数 Tiff_load : Tiff形式ロード
  351.    fn = ファイル名
  352.    tp = Tiffアクセス構造体
  353. */
  354. int Tiff_load( char *fn, Tiff *tp ) {
  355. FILE *fp;
  356. int i,j,d,tag_n,ofs,palofs,cbit;
  357. char buf[16];
  358.     
  359.     palofs=cbit=0;
  360.     tp->xsize=tp->ysize=0;
  361.     tp->comp=1;
  362.     tp->gmsize=tp->pmsize=0;
  363.     tp->color=0;
  364.     
  365.     if( (fp=fopen( fn,"rb" ))==NULL )
  366.         return( Tiff__NOOPEN );
  367.     
  368.     if( fread( buf, 1, sizeof(Tiff_id), fp )<sizeof(Tiff_id) ) {
  369.         fclose( fp );
  370.         return( Tiff__NOREAD );
  371.     }
  372.     if( cmpdata( buf, &Tiff_id, sizeof(Tiff_id) ) ) {
  373.         fclose( fp );
  374.         return( Tiff__NOTIFF );
  375.     }
  376.     fread( buf, 1, sizeof(unsigned short), fp );
  377.     tag_n=*(unsigned short *)buf;
  378.  
  379.     for( i=0; i<tag_n; i++ ) {
  380.         fread( buf, 1, sizeof(Tiff_tag[0]), fp );
  381.         for( j=0; j<17; j++ ) {
  382.             if( cmpdata( buf, &Tiff_tag[j], sizeof(Tiff_tag[0].tag) )==0 ) {
  383.                 d=((struct tifftag *)buf)->data;
  384.                 switch( j ) {
  385.                     case 1:
  386.                         tp->xsize=d;
  387.                         break;
  388.                     case 2:
  389.                         tp->ysize=d;
  390.                         break;
  391.                     case 3:
  392.                         cbit=d;
  393.                         break;
  394.                     case 4:
  395.                         tp->comp=d;
  396.                         break;
  397.                     case 7:
  398.                         ofs=d;
  399.                         break;
  400.                     case 10:
  401.                         tp->gmsize=d;
  402.                         break;
  403.                     case 11:
  404.                         tp->color=d+1;
  405.                         break;
  406.                     case 15:
  407.                         palofs=d;
  408.                         tp->pmsize=0x60;
  409.                         break;
  410.                     case 16:
  411.                         palofs=d;
  412.                         tp->pmsize=0x600;
  413.                         break;
  414.                 }
  415.             }
  416.         }
  417.     }
  418.     
  419.     if( tp->comp>1 && tp->comp!=5 ) {    /* 圧縮なし or LZW圧縮のみ */
  420.         fclose( fp );
  421.         return( Tiff__ILLCOMP );
  422.     }
  423.     
  424.     if( tp->gmsize==0 ) {        /* gmsizeが設定されていない時の対策 */
  425.         if( tp->comp>1 ) {
  426.             fclose( fp );
  427.             return( Tiff__NOTIFF );
  428.         }
  429.         tp->comp=1;
  430.         tp->gmsize=(tp->xsize*tp->ysize*cbit)/8;
  431.     }
  432.  
  433.     if( palofs>0 ) {
  434.         if( (tp->pmem=(char *)malloc( tp->pmsize ))==NULL ) {
  435.             fclose( fp );
  436.             return( Tiff__NOMEM );
  437.         }
  438.         fseek( fp, palofs, SEEK_SET );
  439.         fread( tp->pmem, sizeof(char), tp->pmsize, fp );
  440.     }
  441.     else {
  442.         tp->pmem=NULL;
  443.         tp->pmsize=0;
  444.     }
  445.     
  446.     if( (tp->gmem=(char *)malloc( tp->gmsize ))==NULL ) {
  447.         fclose( fp );
  448.         return( Tiff__NOMEM );
  449.     }
  450.     fseek( fp, ofs, SEEK_SET );
  451.     fread( tp->gmem, sizeof(char), tp->gmsize, fp );
  452.     
  453.     fclose( fp );
  454.     return( Tiff__OK );
  455. }
  456.  
  457.  
  458. /* 関数 Tiff_decompress : Tiff LZW展開
  459.    tp = Tiffアクセス構造体
  460. */
  461. int Tiff_decompress( Tiff *tp ) {
  462. int gxsize;
  463. char *gxmem;
  464.  
  465.     if( tp->comp==1 )
  466.         return( Tiff__OK );
  467.  
  468.     if( tp->comp!=5 )
  469.         return( Tiff__ILLCOMP );
  470.     
  471.     gxsize=(tp->xsize)*(tp->ysize);
  472.     switch( tp->color ) {
  473.         case 16:
  474.             gxsize/=2;
  475.             break;
  476.         case 256:
  477.             break;
  478.         case 32768:
  479.             gxsize*=2;
  480.             break;
  481.         default:
  482.             return( Tiff__ILLCOL );
  483.     }
  484.     if( (gxmem=(char *)malloc( gxsize ))==NULL )
  485.         return( Tiff__NOMEM );
  486.  
  487.     if( Tiff__decomp( tp->gmem, gxmem )!=0 ) {
  488.         free( gxmem );
  489.         return( Tiff__NOMEM );
  490.     }
  491.     free( tp->gmem );
  492.     tp->gmem=gxmem;
  493.     tp->gmsize=gxsize;
  494.     tp->comp=1;
  495.     
  496.     return( Tiff__OK );
  497. }
  498.  
  499.  
  500. /* 関数 Tiff_compress : Tiff LZW圧縮
  501.    tp = Tiffアクセス構造体
  502. */
  503. int Tiff_compress( Tiff *tp ) {
  504. int gcsize;
  505. char *gcmem;
  506.  
  507.     if( tp->comp!=1 )
  508.         return( Tiff__NOCOMP );
  509.  
  510.     gcsize=(tp->gmsize*3)/2;    /* 圧縮後のサイズは圧縮前の1.5倍より
  511.                                     小さい筈である。 */
  512.     if( (gcmem=(char *)malloc( gcsize )) == NULL )
  513.         return( Tiff__NOMEM );
  514.  
  515.     gcsize=Tiff__comp( tp->gmsize, tp->gmem, gcmem );
  516.     if( gcsize<0 ) {
  517.         free( gcmem );
  518.         return( Tiff__NOMEM );
  519.     }
  520.     free( tp->gmem );
  521.     gcmem=realloc( gcmem, gcsize );
  522.     tp->gmem=gcmem;
  523.     tp->gmsize=gcsize;
  524.     tp->comp=5;
  525.     
  526.     return( Tiff__OK );
  527. }
  528.  
  529.  
  530. /* 関数 Tiff_make_palette : Tiffパレット作成
  531.    tp = Tiffアクセス構造体
  532. */
  533. int Tiff_make_palette( Tiff *tp ) {
  534. int i,br,rr,gg,bb;
  535. unsigned short *pa;
  536.  
  537.     if( tp->pmem==NULL ) {
  538.         switch( tp->color ) {
  539.             case 16:
  540.                 tp->pmsize=0x60;
  541.                 break;
  542.             case 256:
  543.                 tp->pmsize=0x600;
  544.                 break;
  545.             default:
  546.                 return( Tiff__ILLCOL );
  547.         }
  548.         if( (tp->pmem=(char *)malloc( tp->pmsize ))==NULL ) {
  549.             return( Tiff__NOMEM );
  550.         }
  551.         rr=gg=bb=0;
  552.         pa=(unsigned short *)(tp->pmem);
  553.         switch( tp->color ) {
  554.             case 16:                    /* パレットの値はFB386に合わせた */
  555.                 br=128;
  556.                 for( i=0; i<16; i++ ) {
  557.                     if( i>=8 )
  558.                         br=255;
  559.                     bb= (i&1)    *br;
  560.                     rr=((i&2)>>1)*br;
  561.                     gg=((i&4)>>2)*br;
  562.                     pa[i]=(rr<<8)|rr;
  563.                     pa[i+16]=(gg<<8)|gg;
  564.                     pa[i+32]=(bb<<8)|bb;
  565.                 }
  566.                 pa[8]=0x4040;
  567.                 pa[8+16]=0x4040;
  568.                 pa[8+32]=0x4040;
  569.                 break;
  570.             case 256:
  571.                 for( i=0; i<256; i++ ) {
  572.                     bb=i & 3;
  573.                     if( bb>0 ) bb=bb*64+63;
  574.                     rr=(i>>2) & 7;
  575.                     if( rr>0 ) rr=rr*32+31;
  576.                     gg=(i>>5) & 7;
  577.                     if( gg>0 ) gg=gg*32+31;
  578.                     pa[i]=(rr<<8)|rr;
  579.                     pa[i+256]=(gg<<8)|gg;
  580.                     pa[i+512]=(bb<<8)|bb;
  581.                 }
  582.                 break;
  583.         }
  584.     }
  585.     return( Tiff__OK );
  586. }
  587.  
  588.  
  589. /* 雑関数 */
  590.  
  591. /* Tiff用パレット調整 */
  592. void adjpal( char *pal, int pasize ) {
  593. int i;
  594. unsigned short *pa;
  595.  
  596.     pa=(unsigned short *)pal;
  597.     for( i=0; i<(pasize/2); i++ ) {
  598.         if( (*pa & 0xff00)==0 )
  599.             *pa=(*pa<<8)|(*pa&255);
  600.         pa++;
  601.     }
  602. }
  603.  
  604.  
  605. /* データ比較 */
  606. int cmpdata( void *p1, void *p2, int n ) {
  607. int i,e=0;
  608.     for( i=0; i<n; i++ ) {
  609.         if( *((char *)p1+i)!=*((char *)p2+i) ) {
  610.             e=1;
  611.             break;
  612.         }
  613.     }
  614.     return( e );
  615. }
  616.  
  617.  
  618. /*  LZW 展開(decompress)  */
  619.  
  620. /* メモリ確保 */
  621. int alloc_mem( void ) {
  622.     if( (Table=(TABLE *)malloc( sizeof(TABLE)*MAXTABLE )) == NULL ) {
  623.         free_mem();
  624.         return( 1 );
  625.     }
  626.     if( (Chain=(CHAIN *)malloc( sizeof(CHAIN)*MAXTABLE )) == NULL ) {
  627.         free_mem();
  628.         return( 1 );
  629.     }
  630.     if( (Hash=(CHAIN **)malloc( sizeof(CHAIN *)*MAXHASH )) == NULL ) {
  631.         free_mem();
  632.         return( 1 );
  633.     }
  634.     return( 0 );
  635. }
  636.  
  637.  
  638. /* メモリ解放 */
  639. void free_mem( void ) {
  640.     if( Table!=NULL )
  641.         free( Table );
  642.     if( Chain!=NULL )
  643.         free( Chain );
  644.     if( Hash!=NULL )
  645.         free( Hash );
  646. }
  647.  
  648.  
  649. /* テーブル初期化 */
  650. void init_table( void ) {
  651. int i;
  652.  
  653.     for( i=0; i<258; i++ ) {
  654.         Table[i].ch=Table[i].cs=i;
  655.         Table[i].next=NULL;
  656.         Table[i].code=i;
  657.         Table[i].hash=i*(MAXTABLE/256);
  658.         Table[i].len=0;
  659.     }
  660.     for( i=0; i<MAXHASH; i++ ) {
  661.         Hash[i]=NULL;
  662.     }
  663. }
  664.  
  665.  
  666. /* 1バイトデータ出力 (マクロ) */
  667. #define put_data( ch ) *(Xmem++)=(char)(ch)
  668. /* void put_data( int ch ) {
  669.     *(Xmem++)=(char)ch;
  670. }*/
  671.  
  672.  
  673. /* テーブルからデータ出力 */
  674. void put_table( int code ) {
  675. TABLE *tbp;
  676. char *xmem;
  677.  
  678.     xmem=( Xmem+=Table[code].len+1 );
  679.     *(--xmem)=Table[code].ch;
  680.     tbp=Table[code].next;
  681.     while( tbp!=NULL ) {
  682.         *(--xmem)=tbp->ch;
  683.         tbp=tbp->next;
  684.     }
  685. }
  686.  
  687.  
  688. /* コードの入力 */
  689. int get_code( void ) {
  690. int d;
  691.  
  692.     while( Ccl<Cbl ) {
  693.         Cc=(Cc<<8)|(*(Pmem++));
  694.         Ccl+=8;
  695.     }
  696.     d=Cc;
  697.     Ccl-=Cbl;
  698.     Cc&=((1<<Ccl)-1);
  699.     d=d>>Ccl;
  700.  
  701.     return( d );
  702. }
  703.  
  704.  
  705. /* テーブル追加 */
  706. void add_table( int s, int c ) {
  707. TABLE *tbp;
  708.  
  709.     tbp=&Table[Table_ix];
  710.     tbp->ch=Table[c].cs;        /* 先頭CODE */
  711.     tbp->cs=Table[s].cs;
  712.     tbp->next=&Table[s];        /* 次のS    */
  713.     tbp->code=Table_ix;
  714.     tbp->len=Table[s].len+1;    /* CODEの長さ */
  715.     Table_ix++;
  716. }
  717.  
  718.  
  719. /* LZW展開(下請け) */
  720. int Tiff__decomp( char *pmem, char *xmem ) {
  721. int code,next,ncbl;
  722.  
  723.     Pmem=pmem;        /* 元データアドレス   */
  724.     Xmem=xmem;        /* 展開データアドレス */
  725.     Cc=Ccl=0;
  726.  
  727.     if( alloc_mem() )
  728.         return( -1 );        /* メモリ確保失敗 */
  729.     init_table();
  730.     Cbl=9;
  731.     ncbl=512-1;
  732.     while( ( next=get_code() )!=EOF_CODE ) {
  733.         if( next==CLEAR_CODE ) {
  734.             Cbl=9;
  735.             ncbl=512-1;
  736.             Table_ix=EOF_CODE+1;            /* 0x102 = 258 */
  737.             if( ( code=get_code() )==EOF_CODE )
  738.                 break;
  739.             put_table( code );
  740.         }
  741.         else if( next<Table_ix ) {
  742.             put_table( next );
  743.             add_table( code, next );        /* S:C */
  744.             if( Table_ix==ncbl && Cbl<12 ) {
  745.                 Cbl++;
  746.                 ncbl=(1<<Cbl)-1;
  747.             }
  748.             code=next;
  749.         }
  750.         else {    /* next==Table_ix */
  751.             put_table( code );                /* S */
  752.             put_data( Table[code].cs );        /* C */
  753.             add_table( code, code );        /* S:C */
  754.             if( Table_ix==ncbl && Cbl<12 ) {
  755.                 Cbl++;
  756.                 ncbl=(1<<Cbl)-1;
  757.             }
  758.             code=next;
  759.         }
  760.     }
  761.     free_mem();
  762.     return( 0 );
  763. }
  764.  
  765.  
  766. /*  LZW 圧縮(compress)  */
  767.  
  768. /* コード出力 */
  769. void put_code( int ch ) {
  770. int d;
  771.  
  772.     Cc=(Cc<<Cbl)|ch;
  773.     Ccl+=Cbl;
  774.     while( Ccl>=8 ) {
  775.         d=Cc;
  776.         Ccl-=8;
  777.         Cc&=((1<<Ccl)-1);
  778.         d>>=Ccl;
  779.         *(Cmem++)=d;
  780.     }
  781. }
  782.  
  783.  
  784. /* データ入力 */
  785. int get_data( void ) {
  786. static int l=0;
  787.     if( (l++)<Psize ) 
  788.         return( *(Pmem++) );
  789.     else {
  790.         l=0;
  791.         return( EOF );
  792.     }
  793. }
  794.  
  795.  
  796. /* テーブル検索 */
  797. TABLE *tsearch( TABLE *s, int c ) {
  798. TABLE *n;
  799. CHAIN *h;
  800.  
  801.     h=Hash[(s->hash+c)&(MAXHASH-1)];
  802.     while( h!=NULL ) {
  803.         n=h->tbl;
  804.         if( n->ch==c && n->next==s )
  805.             return( h->tbl );
  806.         h=h->next;
  807.     }
  808.     return( NULL );
  809. }
  810.  
  811.  
  812. /* エントリ追加 */
  813. void add_entry( TABLE *s, int c ) {
  814. TABLE *tbp;
  815. CHAIN *hc,**ha;
  816.  
  817.     tbp=&Table[Table_ix];
  818.     tbp->ch=c;
  819.     tbp->next=s;
  820.     tbp->code=Table_ix;
  821.     tbp->hash=(s->hash+c-Table_ix);        /* これが試した中で
  822.                                             一番効率が良かった */
  823.     
  824.     ha=&Hash[(s->hash+c)&(MAXHASH-1)];
  825.     hc=&Chain[Chain_ix++];
  826.     hc->next=*ha;
  827.     hc->tbl=tbp;
  828.     *ha=hc;
  829.     
  830.     Table_ix++;
  831. }
  832.  
  833.  
  834. /* LZW圧縮(下請け) */
  835. int Tiff__comp( int size, char *pmem, char *cmem ) {
  836. TABLE *s,*p;
  837. int ch,ncbl;
  838.  
  839.     Psize=size;        /* データサイズ       */
  840.     Pmem=pmem;        /* 元データアドレス   */
  841.     Cmem=cmem;        /* 圧縮データアドレス */
  842.     Cc=Ccl=0;
  843.  
  844.     if( alloc_mem() )
  845.         return( -1 );        /* メモリ確保失敗 */
  846.     init_table();
  847.     Cbl=9;
  848.     ncbl=512;
  849.     Table_ix=EOF_CODE+1;
  850.     Chain_ix=0;
  851.     put_code( CLEAR_CODE );
  852.     
  853.     if( (ch=get_data())==EOF )
  854.         return( 0 );
  855.     s=&Table[ch];
  856.     while( (ch=get_data())!=EOF ) {
  857.         if( (p=tsearch( s, ch ))!=NULL ) {
  858.             s=p;
  859.         }
  860.         else {
  861.             put_code( s->code );                /* S */
  862.             if( Table_ix<(MAXTABLE-1) ) {
  863.                 add_entry( s, ch );                /* S:C */
  864.                 if( Table_ix==ncbl && Cbl<12 ) {
  865.                     Cbl++;
  866.                     ncbl=(1<<Cbl);
  867.                 }
  868.             }
  869.             else {
  870.                 put_code( CLEAR_CODE );
  871.                 init_table();
  872.                 Cbl=9;
  873.                 ncbl=512;
  874.                 Table_ix=EOF_CODE+1;
  875.                 Chain_ix=0;
  876.             }
  877.             s=&Table[ch];
  878.         }
  879.     }
  880.     put_code( s->code );
  881.     put_code( EOF_CODE );
  882.     Cbl=7;
  883.     put_code( 0 );        /* flush */
  884.  
  885.     free_mem();
  886.     return( (int)(Cmem-cmem) );        /* 圧縮サイズ */
  887. }
  888.  
  889.